home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickTime Conferencing / Programming Stuff / Sample Code / SeeWorld / See.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-23  |  12.7 KB  |  726 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        See.c
  3.  
  4.     Contains:    A Sample MovieTalk Conferencing Application
  5.  
  6.     Written by:    Guy Riddle
  7.  
  8.     Copyright:    © 1994 by Apple Computer, Inc., all rights reserved.
  9.  
  10. */
  11.  
  12. #include <Types.h>
  13. #include <QuickDraw.h>
  14. #include <Fonts.h>
  15. #include <Events.h>
  16. #include <Windows.h>
  17. #include <Menus.h>
  18. #include <Dialogs.h>
  19. #include <Desk.h>
  20. #include <ToolUtils.h>
  21. #include <Memory.h>
  22. #include <Resources.h>
  23. #include <SegLoad.h>
  24. #include <Files.h>
  25. #include <Folders.h>
  26. #include <OSUtils.h>
  27. #include <DiskInit.h>
  28. #include <Scrap.h>
  29.  
  30. #include <String.h>
  31. #include <Strings.h>
  32. #include <stdio.h>
  33.  
  34. #include <QuickTimeConferencing.h>
  35.  
  36. #include "See.h"
  37.  
  38. typedef    EventRecord            *EventRecordPtr;
  39. typedef    Byte                *BytePtr;
  40.  
  41. #define        PW_CLEAR        'pw-C'    
  42.  
  43. #define        MAXMEMBERS        3
  44.  
  45. typedef struct {
  46.     Rect                    box;
  47.     MTConferenceMember        member;
  48.     MTControllerComponent    controller;
  49. } Member, *MemberPtr;
  50.  
  51. #define        WRECT(top, left)    (top),(left),(top+120),(left+160)
  52.  
  53.     Member                    gMember[MAXMEMBERS+1]    = {
  54.                                 {    WRECT(100, 100)        },
  55.                                 {    WRECT(100, 300)        },
  56.                                 {    WRECT(300, 100)        },
  57.                                 {    WRECT(300, 300)        },
  58.                             };
  59.                             
  60.     MTCString63                gUserName, gPassword;
  61.     
  62.     ComponentInstance        gCC, gBC;
  63.     MTConferenceToken        gConference;
  64.     
  65.     MemberPtr        FindMember(MTConferenceMember);
  66.     
  67.     void            Initialize(void);
  68.     void            StartMovieTalk(void);
  69.     void            StopMovieTalk(void);
  70.     void            EventLoop(void);
  71.     
  72.     void            DoToolboxEvent(EventRecordPtr);
  73.     void            DoKeyDownEvent(EventRecordPtr);
  74.     void            DoMouseDownEvent(EventRecordPtr);
  75.     void            DoDiskEvent(EventRecordPtr);
  76.     void            AdjustMenus(void);
  77.     void            DoMenuBar(long);
  78.     void            DoAppleMenu(short);
  79.     void            DoFileMenu(short);
  80.     void            DoVideoPhoneMenu(short);
  81.     void            DoMenuCall(void);
  82.     void            DoMenuHangUp(void);
  83.     
  84.     void            DoConferenceEvent(MTConferenceEventPtr);
  85.     void            DoConfReady(MTConferenceEventPtr);
  86.     void            DoMemberReady(MTConferenceEventPtr);
  87.     void            DoMemberTerminated(MTConferenceEventPtr);
  88.     void            DoConfTerminated(MTConferenceEventPtr);
  89.     void            DoPhoneRinging(MTConferenceEventPtr);
  90.     Boolean            Requires(MTConferenceMember, OSType);
  91.     Handle            GetPassword(Ptr);
  92.     void            EnableButton(DialogRef, short, Boolean);
  93.     void            GetValue(BytePtr, DialogRef, short);
  94.     void            DoIncomingCall(MTConferenceEventPtr);
  95.     void            DoMemberJoining(MTConferenceEventPtr);
  96.  
  97.     void            CallOne(MTNamePtr);
  98.     void            SaveMovie(Handle);
  99.     void            SaveSnapshot(Handle);
  100.     void            Sorry(int, int, MTConferenceMember, OSErr);
  101.  
  102. /*
  103.  *    See
  104.  *
  105.  *    This application demonstrates basic multi-party conferencing using the MovieTalk
  106.  *    Conference Component and Browser Component.  It arbitrary limits the total number of
  107.  *    conference members to 4 (including yourself).  Snapshots are just put in the global
  108.  *    clipboard and movies are moved to the desktop.
  109.  *
  110.  *    • Also supported is the clear-text password request dialog for servers that require
  111.  *    authentication.
  112.  */
  113.  
  114. void main()
  115. {
  116.     Initialize();
  117.     EventLoop();
  118. }
  119.  
  120.     void 
  121. Initialize(
  122.     void
  123. ){
  124.     Handle                    menuBar;
  125.     DialogPtr                dp;
  126.  
  127.     InitGraf((Ptr) &qd.thePort);
  128.     InitFonts();
  129.     InitWindows();
  130.     InitMenus();
  131.     TEInit();
  132.     InitDialogs(nil);
  133.     InitCursor();
  134.     
  135.     dp = GetNewDialog(rAboutAlert, nil, (WindowRef) -1);
  136.     DrawDialog(dp);
  137.             
  138.     StartMovieTalk();
  139.  
  140.     menuBar = GetNewMBar(rMenuBar);
  141.  
  142.     SetMenuBar(menuBar);
  143.     DisposHandle(menuBar);
  144.     AddResMenu(GetMHandle(mApple), 'DRVR');
  145.  
  146.     DrawMenuBar();
  147.     
  148.     DisposeDialog(dp);
  149. }
  150.  
  151.     void
  152. StartMovieTalk(
  153.     void
  154. ){
  155.     StringHandle            sh;
  156.     Handle                    srvt;
  157.  
  158.     sh = GetString(kMTAppleTalkUserName);
  159.     
  160.     strncpy((char*)gUserName, (const char*)*sh+1, (size_t)**sh);
  161.     
  162.     gCC = OpenDefaultComponent(kMTConferenceType, kMTMovieTalkSubType);
  163.     
  164.     gMember[0].controller = MTConferenceNewPreparedController(gCC, &gMember[0].box,
  165.                               mtMediaSourcePrepMask+mtGrabVideoPrepMask+mtGrabAudioPrepMask+mtWindowVisiblePrepMask+mtControllerVisiblePrepMask+mtEnableSnapshotPrepMask+mtEnableRecordPrepMask,
  166.                               0);
  167.                               
  168.     srvt = GetResource('srvt', rServiceTypes);
  169.     HLock(srvt);
  170.     
  171.     MTConferenceListen(gCC, gUserName, gUserName, (MTCString)*srvt);
  172.     ReleaseResource(srvt);
  173.     
  174.     gBC = OpenDefaultComponent(kMTBrowserType, kMTAppleTalkSubType);
  175. }                            
  176.  
  177.     void
  178. EventLoop(
  179.     void
  180. ){
  181.     EventRecord                tEvent;
  182.     MTConferenceEvent        cEvent;
  183.  
  184.     for(;;){
  185.         if(MTConferenceGetNextEvent(gCC, &cEvent))
  186.             DoConferenceEvent(&cEvent);
  187.             
  188.         if(WaitNextEvent(everyEvent, &tEvent, 1, 0))
  189.             DoToolboxEvent(&tEvent);
  190.     }
  191. }
  192.  
  193.     void
  194. DoToolboxEvent(
  195.     EventRecordPtr            ev
  196. ){
  197.     switch(ev->what) {
  198.     case mouseDown:
  199.         DoMouseDownEvent(ev);
  200.         break;
  201.     
  202.     case keyDown:
  203.         DoKeyDownEvent(ev);
  204.         break;
  205.     
  206.     case diskEvt:
  207.         DoDiskEvent(ev);
  208.     }
  209. }
  210.  
  211.     void
  212. DoMouseDownEvent(
  213.     EventRecordPtr            ev
  214. ){
  215.     WindowPtr                wp;
  216.     short                    part;
  217.     
  218.     part = FindWindow(ev->where, &wp);
  219.     
  220.     switch(part){
  221.     case inMenuBar:
  222.         AdjustMenus();
  223.         DoMenuBar(MenuSelect(ev->where));
  224.     }
  225. }
  226.  
  227.     void
  228. DoKeyDownEvent(
  229.     EventRecordPtr            ev
  230. ){
  231.     if(ev->modifiers & cmdKey){
  232.         AdjustMenus();    
  233.         DoMenuBar(MenuKey(ev->message & charCodeMask));
  234.     }
  235. }
  236.  
  237.     void
  238. DoDiskEvent(
  239.     EventRecordPtr            ev
  240. ){
  241.     Point                    where;
  242.  
  243.     if(HiWord(ev->message)){
  244.         SetPt(&where, kDILeft, kDITop);
  245.         DIBadMount(where, ev->message);
  246.     }
  247. }
  248.  
  249.     void
  250. AdjustMenus(
  251.     void
  252. ){
  253.     MenuHandle                mh;
  254.     
  255.     mh = GetMHandle(mVideoPhone);
  256.     
  257.     gConference ? EnableItem(mh, iHangUp) : DisableItem(mh, iHangUp);
  258.     FindMember(0) ? EnableItem(mh, iCall) : DisableItem(mh, iCall);
  259. }
  260.  
  261.     void
  262. DoMenuBar(
  263.     long                    selection
  264. ){
  265.     short                    menuID;    
  266.     short                    menuItem;
  267.  
  268.     menuID = HiWord(selection);
  269.     menuItem = LoWord(selection);
  270.     
  271.     switch(menuID){
  272.     case mApple:
  273.         DoAppleMenu(menuItem);
  274.         break;
  275.         
  276.     case mFile:
  277.         DoFileMenu(menuItem);
  278.         break;
  279.         
  280.     case mEdit:                    /* call SystemEdit for DA editing & MultiFinder */
  281.         SystemEdit(menuItem-1);
  282.         break;
  283.         
  284.     case mVideoPhone:
  285.         DoVideoPhoneMenu(menuItem);
  286.     }
  287.     
  288.     HiliteMenu(0);
  289. }
  290.  
  291.     void
  292. DoAppleMenu(
  293.     short                    item
  294. ){
  295.     DialogRef                dp;
  296.     Str255                    daName;
  297.     short                    itemHit;
  298.  
  299.     switch(item){
  300.     case iAbout:
  301.         dp = GetNewDialog(rAboutAlert, nil, (WindowRef) -1);
  302.         SetDialogDefaultItem(dp, 1);
  303.         
  304.         ModalDialog(0, &itemHit);
  305.         
  306.         DisposeDialog(dp);
  307.         break;
  308.         
  309.     default:            /* all non-About items in this menu are DAs */
  310.         GetItem(GetMHandle(mApple), item, daName);
  311.         OpenDeskAcc(daName);
  312.     }
  313. }
  314.  
  315.     void
  316. DoFileMenu(
  317.     short                    item
  318. ){
  319.     switch(item){
  320.     case iQuit:
  321.         StopMovieTalk();
  322.         
  323.         ExitToShell();
  324.     }
  325. }
  326.  
  327.     void
  328. DoVideoPhoneMenu(
  329.     short                    item
  330. ){
  331.     switch(item){
  332.     case iCall:
  333.         DoMenuCall();
  334.         break;
  335.         
  336.     case iHangUp:
  337.         DoMenuHangUp();
  338.     }
  339. }
  340.  
  341.     void
  342. StopMovieTalk(
  343.     void
  344. ){
  345.     CloseComponent(gCC);
  346.     CloseComponent(gBC);
  347. }
  348.  
  349.     void
  350. DoMenuCall(
  351.     void
  352. ){
  353.     MTNameListPtr            names;
  354.     MTNamePtr                np;
  355.     int                        count;
  356.     
  357.     if(MTBrowserBrowse(gBC, 0, "\pLets go Fishing…", (MTCString)"mtlkatlk\tVideoPhone\x0Dmtlktcpi\t458\x0Dmtlkatlk\tMulticaster\x0Dmtlktcpi\t545\x0Dmtlkisdn\t-\x0D", 0, &names) != noErr)
  358.         return;
  359.         
  360.     count = GetMTNameListCount(names);
  361.     np = &(names->list[0]);
  362.  
  363.     while(--count >= 0)
  364.         CallOne(np++);
  365.         
  366.     DisposeMTNameList(names);
  367. }
  368.  
  369.     void
  370. CallOne(
  371.     MTNamePtr                np
  372. ){
  373.     MemberPtr                mp;
  374.     
  375.     if(!(mp = FindMember(0)))
  376.         return;
  377.         
  378.     mp->member = MTConferenceCall(gCC, (unsigned char*)"See Wiz", np);
  379. }
  380.  
  381.     void
  382. DoMenuHangUp(
  383.     void
  384. ){
  385.     MTConferenceTerminate(gCC, gConference);
  386.     gConference = 0;        // just to suppress menu choice
  387. }
  388.  
  389.     void
  390. DoConferenceEvent(
  391.     MTConferenceEventPtr    ce
  392. ){
  393.     switch(ce->what){
  394.     case mtIncomingCallEvent:
  395.         DoIncomingCall(ce);
  396.         break;
  397.     
  398.     case mtMemberJoiningEvent:
  399.         DoMemberJoining(ce);
  400.         break;
  401.  
  402.     case mtConferenceReadyEvent:
  403.         DoConfReady(ce);
  404.         break;
  405.     
  406.     case mtConferenceTerminatedEvent:
  407.         DoConfTerminated(ce);
  408.         break;
  409.     
  410.     case mtMemberReadyEvent:
  411.         DoMemberReady(ce);
  412.         break;
  413.     
  414.     case mtMemberTerminatedEvent:
  415.         DoMemberTerminated(ce);
  416.         break;
  417.     
  418.     case mtPhoneRingingEvent:
  419.         DoPhoneRinging(ce);
  420.         break;
  421.     
  422.     case mtRefusedEvent:
  423.         Sorry(701, 1, ce->who, ce->err);
  424.         break;
  425.     
  426.     case mtFailedEvent:
  427.         Sorry(701, 2, ce->who, ce->err);
  428.         break;
  429.         
  430.     case mtSnapshotTakenEvent:
  431.         SaveSnapshot(ce->surprise);
  432.         break;
  433.         
  434.     case mtMovieRecordedEvent:
  435.         SaveMovie(ce->surprise);
  436.     }
  437.     
  438.     if(ce->surprise)
  439.         DisposeHandle(ce->surprise);
  440. }
  441.  
  442.     void
  443. DoIncomingCall(
  444.     MTConferenceEventPtr    ce
  445. ){
  446.     MemberPtr                mp;
  447.     OSErr                    reason;
  448.     
  449.     reason = 0;
  450.     
  451.     if((ce->bonus & mtSendMediaModeMask) && !(ce->bonus & mtReceiveMediaModeMask))
  452.         reason = mtConnectionRefusedErr;        // no peeking
  453.     else if(mp = FindMember(0))
  454.         mp->member = ce->who;
  455.     else{
  456.         reason = paramErr;
  457.         
  458.         Sorry(702, 1, ce->who, 0);
  459.     }
  460.         
  461.     MTConferenceReply(gCC, ce->who, reason);
  462. }
  463.  
  464.     void
  465. DoMemberJoining(
  466.     MTConferenceEventPtr    ce
  467. ){
  468.     MemberPtr                mp;
  469.     
  470.     if(mp = FindMember(0))
  471.         mp->member = ce->who;
  472.     else
  473.         Sorry(702, 2, ce->who, 0);
  474. }
  475.  
  476.     void
  477. DoConfReady(
  478.     MTConferenceEventPtr    ce
  479. ){
  480.     if(gConference)
  481.         MTConferenceMerge(gCC, gConference, ce->who);
  482.     else
  483.         MTConferenceActivateConference(gCC, gConference = ce->who, gMember[0].controller);
  484. }
  485.  
  486.     void
  487. DoMemberReady(
  488.     MTConferenceEventPtr    ce
  489. ){
  490.     MemberPtr                mp;
  491.     MTControllerComponent    mtc;
  492.     
  493.     
  494.     if(ce->bonus & mtReceiveMediaModeMask){    
  495.         if(!(mp = FindMember(ce->who)))
  496.             return;
  497.     
  498.         mtc = MTConferenceNewPreparedController(gCC, &mp->box,
  499.                mtWindowVisiblePrepMask+mtControllerVisiblePrepMask+mtEnableSnapshotPrepMask+mtEnableRecordPrepMask,
  500.                MTConferenceGetMemberName(gCC, mp->member));
  501.                
  502.         mp->controller = mtc;
  503.     }else
  504.         mtc = 0;
  505.                        
  506.     MTConferenceActivateMember(gCC, ce->who, mtc);
  507. }
  508.  
  509.     void
  510. DoMemberTerminated(
  511.     MTConferenceEventPtr    ce
  512. ){
  513.     MemberPtr                mp;
  514.     
  515.     if(!(mp = FindMember(ce->who)))
  516.         return;
  517.         
  518.     if(mp->controller)
  519.         MTConferenceDisposeController(gCC, mp->controller);
  520.         
  521.     mp->controller = 0;
  522.     mp->member = 0;
  523. }
  524.  
  525.     void
  526. DoConfTerminated(
  527.     MTConferenceEventPtr    ce
  528. ){
  529.     if(gConference == ce->who)
  530.         gConference = 0;
  531. }
  532.  
  533.     void
  534. DoPhoneRinging(
  535.     MTConferenceEventPtr    ce
  536. ){
  537.     Handle                    ph;
  538.     
  539.     if((ce->bonus & mtRequiredMessagesModeMask) && Requires(ce->who, PW_CLEAR) && (ph = GetPassword((Ptr)MTConferenceGetMemberName(gCC, ce->who))))
  540.         MTConferenceSendMessageToMember(gCC, ce->who, ph, PW_CLEAR, 1);
  541. }
  542.  
  543.     Boolean
  544. Requires(
  545.     MTConferenceMember        who,
  546.     OSType                    type
  547. ){
  548.     MTCapabilitiesHandle    ch;
  549.     MTCapabilitiesPtr        cp;
  550.     int                        n;
  551.     
  552.     ch = MTConferenceGetMemberMessageCapabilities(gCC, who);
  553.     
  554.     for(n = (*ch)->count, cp = (*ch)->capability; --n >= 0; cp++)
  555.         if(type == cp->messageType && cp->desires == mtMessageRequiredCapability){
  556.             DisposeHandle((Handle) ch);
  557.             return(true);
  558.         }
  559.     
  560.     DisposeHandle((Handle) ch);
  561.     return(false);
  562. }
  563.  
  564.     Handle
  565. GetPassword(
  566.     Ptr                        name
  567. ){
  568.     DialogRef                dp;
  569.     short                    itemHit;
  570.     Handle                    ph;
  571.     Str255                    p1;
  572.     Str255                    p2;
  573.     
  574.     p2[0] = 0;
  575.     ParamText(p2, c2pstr(strcpy(p1, (char*)name)), p2, p2);
  576.     gPassword[0] = 0;
  577.     
  578.     dp = GetNewDialog(rPassword, 0, (WindowRef) -1);
  579.     SetDialogDefaultItem(dp, diOK);
  580.     SetDialogCancelItem(dp, diCancel);
  581.     SetDialogTracksCursor(dp, true);
  582.     PostEvent(keyDown, '\b');        // ick
  583.     
  584.     do{
  585.         EnableButton(dp, diOK, gPassword[0]);
  586.         
  587.         ModalDialog(0, &itemHit);
  588.         
  589.         GetValue(gPassword, dp, diPassword);
  590.     }while(itemHit > diCancel);
  591.     
  592.     DisposeDialog(dp);
  593.     InitCursor();
  594.     
  595.     if(itemHit == diCancel)
  596.         return(0);
  597.     
  598.     PtrToHand(gPassword, &ph, strlen((char*)gPassword)+1);
  599.     
  600.     return(ph);
  601. }
  602.  
  603.     void
  604. EnableButton(
  605.     DialogRef                dp,
  606.     short                    item,
  607.     Boolean                    enabled
  608. ){
  609.     Handle                    ih;
  610.     Rect                    rect;
  611.     short                    type;
  612.     
  613.     GetDialogItem(dp, item, &type, &ih, &rect);
  614.     
  615.     if(enabled)
  616.         type &= ~itemDisable;
  617.     else
  618.         type |= itemDisable;
  619.         
  620.     HiliteControl((ControlHandle) ih, enabled ? 0 : 255);
  621.     
  622.     SetDialogItem(dp, item, type, ih, &rect);
  623.     
  624.     SetPort(dp);
  625.     InsetRect(&rect, -5, -5);
  626.     InvalRect(&rect);
  627. }
  628.  
  629.     void
  630. GetValue(
  631.     BytePtr                    p,
  632.     DialogRef                dp,
  633.     short                    item
  634. ){
  635.     Handle                    ih;
  636.     Rect                    rect;
  637.     short                    type;
  638.     
  639.     GetDialogItem(dp, item, &type, &ih, &rect);
  640.     GetDialogItemText(ih, p);
  641.     
  642.     if(p[0] && p[p[0]] < ' '){
  643.         p[0]--;            // strip CR or other junk
  644.         SetDialogItemText(ih, p);
  645.     }
  646.     
  647.     p2cstr(p);
  648. }
  649.  
  650.     void
  651. SaveSnapshot(
  652.     Handle                    pic
  653. ){
  654.     ZeroScrap();
  655.     
  656.     HLock(pic);
  657.     
  658.     PutScrap(GetHandleSize(pic), 'PICT', *pic);
  659. }
  660.  
  661.     void
  662. SaveMovie(
  663.     Handle                    h
  664. ){
  665.     Ptr                        p;
  666.     int                        i;
  667.     long                    dirid;
  668.     short                    vrefnum;
  669.     FSSpecPtr                temp;
  670.     FSSpec                    spec;
  671.     Str255                    newname;
  672.     
  673.     HLock(h);
  674.     temp =(FSSpecPtr) *h;
  675.     
  676.     FindFolder(kOnSystemDisk, kDesktopFolderType, true, &vrefnum, &dirid);
  677.     FSMakeFSSpec(vrefnum, dirid, c2pstr(""), &spec);
  678.     FSpCatMove(temp, &spec);        // move it to the desktop
  679.     
  680.     FSMakeFSSpec(vrefnum, dirid, temp->name, &spec);
  681.     GetIndString(newname, rWildSTRs, srMovieName);
  682.     p = (Ptr)strchr(p2cstr(newname), '?');
  683.     
  684.     for(i = 1; i < 10; i++){
  685.         *p = '0'+i;
  686.         
  687.         if(FSpRename(&spec, newname) == noErr)
  688.             return;                    // and give it a better name
  689.     }
  690.     
  691.     SysBeep(1);
  692. }
  693.     
  694.     MemberPtr
  695. FindMember(
  696.     MTConferenceMember        who
  697. ){
  698.     int                        i;
  699.     
  700.     for(i = 1; i <= MAXMEMBERS; i++)
  701.         if(who == gMember[i].member)
  702.             return(&gMember[i]);
  703.             
  704.     return(0);
  705. }
  706.  
  707.     void
  708. Sorry(
  709.     int                        why,
  710.     int                        note,
  711.     MTConferenceMember        who,
  712.     OSErr                    err
  713. ){
  714.     Str255                    p1;
  715.     char*                    p2;
  716.     Str255                    p3;
  717.     
  718.     GetIndString(p1, why, note);
  719.     
  720.     p2 = (char*)MTConferenceGetMemberName(gCC, who);
  721.     sprintf(p3, "%d", err);
  722.     
  723.     ParamText(c2pstr(""), p1, c2pstr(p2), c2pstr(p3));
  724.     
  725.     CautionAlert(why, 0);
  726. }